(function() {
	var imp, log, server, context, conf;

	try {
		importer();
		loadConfig();
		configLog();
		loadScripts();
		startMonit();
		startServer();
	} catch (e) {
		log.error("Start Server Error: " + e, e.javaException);
	}

	function importer() {
		imp = JavaImporter(
			java.io,
			org.eclipse.jetty.server,
			org.eclipse.jetty.servlet,
			com.pandajs,
			org.apache.log4j,
			org.slf4j);
	}

	function loadConfig() {
		load("scripts/config.js");
		conf = config.server;
	}

	function configLog() {
		imp.PropertyConfigurator.configure(conf.logConfigPath);
		log = imp.LoggerFactory.getLogger("server");
	}

	function loadScripts() {
		log.info("Loading Scripts ...");
		loadDirs(conf.scriptsDirs.concat(conf.servletsDirs));
	}

	function startMonit() {
		log.info("Starting Monit ...");

		panda.monit(conf.scriptsDirs, function(file){
			file = imp.File(file);
			if(file.exists() && file.name.endsWith(".js")) {
				load(file);
			} else if (file.directory) {
				this[file.name] = {};
			}
		});
	}

	function startServer() {
		log.info("Starting Server ...");
		createServer();
		server.start();
		server.join();
	}

	function loadDirs(dirs) {
		each(dirs, function(dir) {
			loadDir(imp.File(dir));		
		});
	}

	function loadDir(dir) {
		this[dir.name] = {};
		each(dir.listFiles(), loadFile);
	}

	function loadFile(file) {
		if (!file.name.startsWith(".")) {
			file.file ? load(file) : loadDir(file);
		}
	}

	function createServer() {
		server = imp.Server(conf.port);
		context();		
		apiServlet();
		pageServlet();
		defaultSerlvlet();
		fileFilter();
	}

	function context() {
		var sessions = imp.ServletContextHandler.SESSIONS;
		context = imp.ServletContextHandler(sessions);
		context.setContextPath(conf.contextPath);
		context.setResourceBase(conf.resourceBase);
		server.setHandler(context);
	}

	function apiServlet() {
		var holder = imp.ServletHolder(servlets.api);
		context.addServlet(holder, conf.apiServletPath);
	}

	function pageServlet() {
		var holder = imp.ServletHolder(servlets.page);
		context.addServlet(holder, conf.pageServletPath);
	}

	function defaultSerlvlet() {
		var servlet = imp.DefaultServlet();
		var holder = imp.ServletHolder(servlet);
		context.addServlet(holder, conf.defaultServletPath);
	}

	function fileFilter() {
		var holder = imp.FilterHolder(imp.MultiPartFilter);
		holder.setInitParameter("deleteFiles", "true");
		holder.setInitParameter("maxSize", conf.maxUploadSize + "");
		context.addFilter(holder, "/api", imp.FilterMapping.DEFAULT);
	}

	function each(array, callback) {
		var i = 0, l = array.length;
		while (i < l) { callback(array[i++]); }
	}
}());
